package main

import (
	"NosqlMongo/common"
	"context"
	"fmt"
	"github.com/pkg/errors"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"log"
	"time"
)

type Student struct {
	Name string
	Age  int
}

func checkError(err error) {
	if err != nil {
		log.Printf("%+v", err)
	}
}
func main() {
	db := common.GetDb()
	defer db.Disconnect(context.Background())
	//插入一条数据
	err := insertOne(db)
	if err != nil {
		log.Printf("%+v", err)
		return
	}
	//插入多条数据
	//查找数据
	err = find(db)
	if err != nil {
		log.Printf("%+v", err)
		return
	}
	//更新数据
	err = update(db)
	if err != nil {
		log.Printf("%+v", err)
		return
	}
	//删除数据
	err = delete(db)
	if err != nil {
		log.Printf("%+v", err)
		return
	}
}

//添加单个文档
func insertOne(db *mongo.Client) (err error) {
	collection := db.Database("test_goods").Collection("collection")
	s1 := Student{"xiaoming", 12}
	insertResult, err := collection.InsertOne(context.Background(), s1)
	if err != nil {
		return errors.Wrap(err, "ERR: fail to insert")
	}
	fmt.Println("Inserted a single document: ", insertResult.InsertedID)
	return nil
}

//添加多个文档
func insertMore(db *mongo.Client) (err error) {
	s1 := Student{"tom", 20}
	s2 := Student{"kite", 21}
	s3 := Student{"rose", 22}
	s4 := []interface{}{s1, s2, s3}
	collection := db.Database("test_goods").Collection("collection")
	insertManyResult, err := collection.InsertMany(context.Background(), s4)
	if err != nil {
		return errors.Wrap(err, "ERR: fail to insert")
	}
	fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)
	return nil
}

//查找文档
func find(mocli *mongo.Client) (err error) {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()
	collection := mocli.Database("test_goods").Collection("collection")
	cur, err := collection.Find(ctx, bson.D{})
	if err != nil {
		return errors.Wrap(err, "ERR: fail to find")
	}
	defer cur.Close(ctx)
	for cur.Next(ctx) {
		var result bson.D
		err := cur.Decode(&result)
		if err != nil {
			return errors.Wrap(err, "ERR: fail to decode")
		}
		fmt.Printf("result: %v\n", result)
	}
	return nil
}

//更新文档
func update(db *mongo.Client) (err error) {
	c := db.Database("test_goods").Collection("collection")
	filter := bson.D{{"name", "tom"}}
	//如果过滤的文档不存在，则插入新的文档
	opts := options.Update().SetUpsert(true)
	update := bson.D{
		{"$set", bson.D{
			{"name", "sunwukong"}},
		}}
	result, err := c.UpdateMany(context.Background(), filter, update, opts)
	if err != nil {
		return errors.Wrap(err, "ERR: fail to update")
	}
	fmt.Printf("ur.ModifiedCount: %v\n", result.ModifiedCount)
	return nil
}

//删除文档
func delete(db *mongo.Client) (err error) {
	c := db.Database("test_goods").Collection("collection")
	filter := bson.D{{"name", "sunwukong"}}
	deleteResult, err := c.DeleteMany(context.Background(), filter)
	if err != nil {
		return errors.Wrap(err, "ERR: fail to delete")
	}
	fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult.DeletedCount)
	return nil
}
